package cn.iocoder.yudao.module.iot.controller.app.product;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.iot.controller.app.device.vo.IotAppProductRespVO;
import cn.iocoder.yudao.module.iot.controller.app.product.vo.IotAppCreateUserProductReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.service.product.IotProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;

@Tag(name = "用户 APP - IoT 产品管理")
@RestController
@RequestMapping("/iot/product")
@Slf4j
public class IotAppProductController {

    @Resource
    private IotProductService productService;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/list")
    @Operation(summary = "获取所有可用产品列表")
    public CommonResult<List<IotAppProductRespVO>> getProductList() {
        List<IotProductDO> list = productService.selectAvailableProductList();
        List<IotAppProductRespVO> result = list.stream().map(product -> {
            IotAppProductRespVO vo = new IotAppProductRespVO();
            vo.setId(product.getId());
            vo.setName(product.getName());
            vo.setCategoryId(product.getCategoryId());
            vo.setPicUrl(product.getPicUrl());
            vo.setNetType(product.getNetType());
            vo.setProtocolType(product.getProtocolType());
            vo.setProtocolId(product.getProtocolId());
            vo.setDataFormat(product.getDataFormat());
            vo.setValidateType(product.getValidateType());
            vo.setTenantId(product.getTenantId());
            vo.setCodecType(product.getCodecType());
            vo.setMac(product.getMac());
            vo.setCreateTime(product.getCreateTime());
            vo.setUpdateTime(product.getUpdateTime());
            vo.setDeleted(product.getDeleted());
            vo.setCreator(product.getCreator());
            vo.setUpdater(product.getUpdater());
            return vo;
        }).collect(Collectors.toList());
        return CommonResult.success(result);
    }

    @GetMapping("/list-master-by-user")
    @Operation(summary = "根据用户ID获取主机产品列表")
    public CommonResult<List<IotAppProductRespVO>> getMasterProductListByUser(@RequestParam Long userId, @RequestParam(required = false) Long roomId) {
        String sql;
        List<Object> params = new ArrayList<>();
        params.add(userId);
        
        if (roomId != null) {
            sql = "SELECT p.*, up.product_name FROM iot_user_product up JOIN iot_product p ON up.product_id = p.id WHERE up.user_id = ? AND up.room_id = ? AND up.MasterSlave = 'Master' AND (p.deleted = 0 OR p.deleted IS NULL)";
            params.add(roomId);
        } else {
            sql = "SELECT p.*, up.product_name FROM iot_user_product up JOIN iot_product p ON up.product_id = p.id WHERE up.user_id = ? AND up.MasterSlave = 'Master' AND (p.deleted = 0 OR p.deleted IS NULL)";
        }
        
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, params.toArray());
        List<IotAppProductRespVO> result = new ArrayList<>();
        for (Map<String, Object> row : rows) {
            IotAppProductRespVO vo = new IotAppProductRespVO();
            
            // 安全的 Long 类型转换
            Object idObj = row.get("id");
            vo.setId(idObj == null ? null : Long.valueOf(idObj.toString()));
            
            vo.setName((String) row.get("product_name")); // 优先用用户产品名
            vo.setProductName((String) row.get("product_name"));
            
            Object categoryIdObj = row.get("category_id");
            vo.setCategoryId(categoryIdObj == null ? null : Long.valueOf(categoryIdObj.toString()));
            
            vo.setPicUrl((String) row.get("pic_url"));
            
            Object netTypeObj = row.get("net_type");
            vo.setNetType(netTypeObj == null ? null : Integer.valueOf(netTypeObj.toString()));
            
            Object protocolTypeObj = row.get("protocol_type");
            vo.setProtocolType(protocolTypeObj == null ? null : Integer.valueOf(protocolTypeObj.toString()));
            
            Object protocolIdObj = row.get("protocol_id");
            vo.setProtocolId(protocolIdObj == null ? null : Long.valueOf(protocolIdObj.toString()));
            
            Object dataFormatObj = row.get("data_format");
            vo.setDataFormat(dataFormatObj == null ? null : Integer.valueOf(dataFormatObj.toString()));
            
            Object validateTypeObj = row.get("validate_type");
            vo.setValidateType(validateTypeObj == null ? null : Integer.valueOf(validateTypeObj.toString()));
            
            Object tenantIdObj = row.get("tenant_id");
            vo.setTenantId(tenantIdObj == null ? null : Long.valueOf(tenantIdObj.toString()));
            
            Object codecTypeObj = row.get("codec_type");
            vo.setCodecType(codecTypeObj == null ? null : String.valueOf(codecTypeObj));
            
            vo.setMac((String) row.get("mac"));
            
            // 时间字段兼容处理
            Object createTimeObj = row.get("create_time");
            if (createTimeObj instanceof java.sql.Timestamp) {
                vo.setCreateTime(((java.sql.Timestamp) createTimeObj).toLocalDateTime());
            } else if (createTimeObj instanceof java.time.LocalDateTime) {
                vo.setCreateTime((java.time.LocalDateTime) createTimeObj);
            }
            
            Object updateTimeObj = row.get("update_time");
            if (updateTimeObj instanceof java.sql.Timestamp) {
                vo.setUpdateTime(((java.sql.Timestamp) updateTimeObj).toLocalDateTime());
            } else if (updateTimeObj instanceof java.time.LocalDateTime) {
                vo.setUpdateTime((java.time.LocalDateTime) updateTimeObj);
            }
            
            Object deletedObj = row.get("deleted");
            vo.setDeleted(deletedObj == null ? null : Boolean.valueOf(deletedObj.toString()));
            
            Object creatorObj = row.get("creator");
            vo.setCreator(creatorObj == null ? null : String.valueOf(creatorObj));
            
            Object updaterObj = row.get("updater");
            vo.setUpdater(updaterObj == null ? null : String.valueOf(updaterObj));
            
            result.add(vo);
        }
        return CommonResult.success(result);
    }

    @GetMapping("/list-slave-by-user")
    @Operation(summary = "根据用户ID获取副机产品列表")
    public CommonResult<List<IotAppProductRespVO>> getSlaveProductListByUser(@RequestParam Long userId, @RequestParam(required = false) Long roomId) {
        String sql;
        List<Object> params = new ArrayList<>();
        params.add(userId);
        
        if (roomId != null) {
            sql = "SELECT p.*, up.product_name FROM iot_user_product up JOIN iot_product p ON up.product_id = p.id WHERE up.user_id = ? AND up.room_id = ? AND up.MasterSlave = 'Slave' AND (p.deleted = 0 OR p.deleted IS NULL)";
            params.add(roomId);
        } else {
            sql = "SELECT p.*, up.product_name FROM iot_user_product up JOIN iot_product p ON up.product_id = p.id WHERE up.user_id = ? AND up.MasterSlave = 'Slave' AND (p.deleted = 0 OR p.deleted IS NULL)";
        }
        
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, params.toArray());
        List<IotAppProductRespVO> result = new ArrayList<>();
        for (Map<String, Object> row : rows) {
            IotAppProductRespVO vo = new IotAppProductRespVO();
            
            // 安全的 Long 类型转换
            Object idObj = row.get("id");
            vo.setId(idObj == null ? null : Long.valueOf(idObj.toString()));
            
            vo.setName((String) row.get("product_name")); // 优先用用户产品名
            vo.setProductName((String) row.get("product_name"));
            
            Object categoryIdObj = row.get("category_id");
            vo.setCategoryId(categoryIdObj == null ? null : Long.valueOf(categoryIdObj.toString()));
            
            vo.setPicUrl((String) row.get("pic_url"));
            
            Object netTypeObj = row.get("net_type");
            vo.setNetType(netTypeObj == null ? null : Integer.valueOf(netTypeObj.toString()));
            
            Object protocolTypeObj = row.get("protocol_type");
            vo.setProtocolType(protocolTypeObj == null ? null : Integer.valueOf(protocolTypeObj.toString()));
            
            Object protocolIdObj = row.get("protocol_id");
            vo.setProtocolId(protocolIdObj == null ? null : Long.valueOf(protocolIdObj.toString()));
            
            Object dataFormatObj = row.get("data_format");
            vo.setDataFormat(dataFormatObj == null ? null : Integer.valueOf(dataFormatObj.toString()));
            
            Object validateTypeObj = row.get("validate_type");
            vo.setValidateType(validateTypeObj == null ? null : Integer.valueOf(validateTypeObj.toString()));
            
            Object tenantIdObj = row.get("tenant_id");
            vo.setTenantId(tenantIdObj == null ? null : Long.valueOf(tenantIdObj.toString()));
            
            Object codecTypeObj = row.get("codec_type");
            vo.setCodecType(codecTypeObj == null ? null : String.valueOf(codecTypeObj));
            
            vo.setMac((String) row.get("mac"));
            
            // 时间字段兼容处理
            Object createTimeObj = row.get("create_time");
            if (createTimeObj instanceof java.sql.Timestamp) {
                vo.setCreateTime(((java.sql.Timestamp) createTimeObj).toLocalDateTime());
            } else if (createTimeObj instanceof java.time.LocalDateTime) {
                vo.setCreateTime((java.time.LocalDateTime) createTimeObj);
            }
            
            Object updateTimeObj = row.get("update_time");
            if (updateTimeObj instanceof java.sql.Timestamp) {
                vo.setUpdateTime(((java.sql.Timestamp) updateTimeObj).toLocalDateTime());
            } else if (updateTimeObj instanceof java.time.LocalDateTime) {
                vo.setUpdateTime((java.time.LocalDateTime) updateTimeObj);
            }
            
            Object deletedObj = row.get("deleted");
            vo.setDeleted(deletedObj == null ? null : Boolean.valueOf(deletedObj.toString()));
            
            Object creatorObj = row.get("creator");
            vo.setCreator(creatorObj == null ? null : String.valueOf(creatorObj));
            
            Object updaterObj = row.get("updater");
            vo.setUpdater(updaterObj == null ? null : String.valueOf(updaterObj));
            
            result.add(vo);
        }
        return CommonResult.success(result);
    }

    @PostMapping("/create")
    @Operation(summary = "创建用户产品关联", description = "创建用户产品关联")
    public CommonResult<Long> createUserProduct(@Valid @RequestBody IotAppCreateUserProductReqVO reqVO) {
        try {
            // 获取当前登录用户ID
            Long userId = SecurityFrameworkUtils.getLoginUserId();
            if (userId == null) {
                return CommonResult.error(401, "用户未登录");
            }

            // 获取产品信息
            String productSql = "SELECT name FROM iot_product WHERE id = ? AND (deleted = 0 OR deleted IS NULL)";
            List<Map<String, Object>> productRows = jdbcTemplate.queryForList(productSql, reqVO.getProductId());
            if (productRows.isEmpty()) {
                return CommonResult.error(400, "产品不存在");
            }
            String productName = (String) productRows.get(0).get("name");

            // 检查是否已存在相同的用户产品关联
            String checkSql = "SELECT COUNT(*) FROM iot_user_product WHERE user_id = ? AND product_id = ? AND deleted = 0";
            Integer count = jdbcTemplate.queryForObject(checkSql, Integer.class, userId, reqVO.getProductId());
            if (count != null && count > 0) {
                return CommonResult.error(400, "该产品已添加，请勿重复添加");
            }

            // 插入用户产品关联
            String insertSql = "INSERT INTO iot_user_product (user_id, product_id, product_name, room_id, MasterSlave, status, create_time, update_time, deleted, tenant_id, creator, updater) VALUES (?, ?, ?, ?, ?, 1, NOW(), NOW(), 0, ?, ?, ?)";
            jdbcTemplate.update(insertSql, 
                userId, 
                reqVO.getProductId(), 
                reqVO.getDeviceName(), // 使用设备名称作为产品名称
                reqVO.getRoomId(), 
                reqVO.getMasterSlave(), 
                1L, // tenantId
                String.valueOf(userId), // creator
                String.valueOf(userId)  // updater
            );

            // 获取插入的ID
            String idSql = "SELECT LAST_INSERT_ID()";
            Long id = jdbcTemplate.queryForObject(idSql, Long.class);

            log.info("用户 {} 成功添加产品 {}, 设备名称: {}, 类型: {}", userId, reqVO.getProductId(), reqVO.getDeviceName(), reqVO.getMasterSlave());
            return CommonResult.success(id);
        } catch (Exception e) {
            log.error("创建用户产品关联失败", e);
            return CommonResult.error(500, "创建失败: " + e.getMessage());
        }
    }

} 